
PM_FUNC_NORM_ATTRIB EncounterAttemptCatch( Int:id, Int:encounterID, Int:encounterHP, Int:encounterMaxHP, Int:iItemUsed )
{
	new Array:playerItems = g_iPlayerItems[ id ];
	new Int:itemNum;
	new bool:bRemoveItem = false;
	if ( iItemUsed == -1 )
	{
		new Int:itemSize = ArraySize( playerItems ) / _:PLAYER_ITEM;
		for ( new Int:iItemID; itemNum < itemSize; itemNum++ )
		{
			iItemID = ArrayGetCell( playerItems, ( ( itemNum * _:PLAYER_ITEM ) + _:ITEM_ID ) );
			if ( _:ArrayGetCell( g_iItemProps, iItemID ) & ( 1 << _:ITEM_AUTO_CATCH ) )
			{
				iItemUsed = iItemID;
				bRemoveItem = true;
				break;
			}
		}
		if ( iItemUsed == -1 )
			return false;
		else
			DHudEventMessage( id, "You used %s.", ItemToName( iItemUsed ) );
	}
	else
	{
		new Int:itemSize = ArraySize( playerItems );
		for ( new Int:iItemID; itemNum < itemSize; itemNum++ )
		{
			iItemID = ArrayGetCell( playerItems, ( ( itemNum * _:PLAYER_ITEM ) + _:ITEM_ID ) );
			if ( iItemID == iItemUsed )
			{
				break;
			}
		}
	}

	new Int:iEncProps = PlayerGetInfo( id, PINFO_ENCOUNTER_PROPS );
	if ( iEncProps & ENCPROP_GHOST )
	{
		DHudEventMessage( id, "The ghost disappeared!" );
		PlayerSetInfo( id, PINFO_ENCOUNTER_POKEMON, 0 );
		return false;
	}

	new Int:iWiggles = EncounterCatch( id, encounterID, iItemUsed, encounterHP, encounterMaxHP, .status_bonus = 1 );
	PlayerSetInfo( id, PINFO_ENCOUNTER_WIGGLES, iWiggles * 2 );

	if ( bRemoveItem && !( _:ArrayGetCell( g_iItemProps, iItemUsed ) & ( 1 << _:ITEM_UNLIMITED_USE ) ) )
	{
		new Int:itemAmount = ArrayGetCell( playerItems, ( ( itemNum * _:PLAYER_ITEM ) + _:ITEM_AMOUNT ) );
		itemAmount--;
		if ( itemAmount > 0 )
			ArraySetCell( playerItems, ( ( itemNum * _:PLAYER_ITEM ) + _:ITEM_AMOUNT ), itemAmount );
		else
		{
			for ( new PLAYER_ITEM:i; i < PLAYER_ITEM; i++ )
			{
				ArrayDeleteItem( playerItems, ( itemNum * _:PLAYER_ITEM ) );
			}
		}
	}

	return true;
}

PM_FUNC_NORM_ATTRIB EncounterImage( Int:id, Int:encounterID, Int:encounterLevel )
{
	static String:szImage[ 16 ];

	// In pokeball
	// (===(O)===)
	new Int:iWiggles = PlayerGetInfo( id, PINFO_ENCOUNTER_WIGGLES );
	if ( iWiggles != 0 )
	{
		if ( iWiggles == 1 || iWiggles == 2 )
			copy( szImage, charsmax(szImage), "=)]< X >[(=" );
		else if ( is_num_odd( iWiggles ) )
			copy( szImage, charsmax(szImage), "(===(O)===)" );
		else
			copy( szImage, charsmax(szImage), " (===(O)===)" );

		if ( iWiggles > 0 )
			iWiggles--;
		else if ( iWiggles < 0 )
		{
			iWiggles++;
			if ( iWiggles == 0 )
			{
				new Int:encounterIVs = PlayerGetInfo( id, PINFO_ENCOUNTER_IVS );
				if ( PlayerGivePoke( id, encounterID, .level = encounterLevel, .pokeIVs = encounterIVs ) )
				{
					new String:szPokeName[ NAME_LEN ];
					PokeToName( encounterID, szPokeName, charsmax(szPokeName) );

					DHudEventMessage( id, "You caught a level %d %s!", encounterLevel, szPokeName );

					PlayerSetInfo( id, PINFO_ENCOUNTER_POKEMON, 0 );

					LocationScript( .iPlayer = id, .iLocation = PlayerGetInfo( id, PINFO_LOCATION ), .szForward = "Catch", .szArgument = szPokeName );
				}
			}
		}
		PlayerSetInfo( id, PINFO_ENCOUNTER_WIGGLES, iWiggles );
	}

	// HP
	// [:::::::---]
	else
	{
		new Int:encounterHP = PlayerGetInfo( id, PINFO_ENCOUNTER_HP );
		if ( encounterHP == -1 )
		{
			PlayerSetInfo( id, PINFO_ENCOUNTER_POKEMON, 0 );
		}
		else
		{
			new Int:encounterIVs = PlayerGetInfo( id, PINFO_ENCOUNTER_IVS );
			new Int:encounterMaxHP = PokemonMaxHP( encounterID, encounterLevel, encounterIVs );

			new Int:iLen;
			szImage[ iLen++ ] = '[';

			new Int:iHealthPercentage = ( 100 * encounterHP ) / encounterMaxHP;
			for ( new Int:iPercent = 1; iPercent < 100; iPercent += 10 )
			{
				szImage[ iLen++ ] = ( iPercent < iHealthPercentage ) ? ':' : '-';
			}

			szImage[ iLen++ ] = ']';

			if ( encounterHP <= 0 )
				PlayerSetInfo( id, PINFO_ENCOUNTER_HP, -1 );
		}
	}

	return szImage;
}

PM_FUNC_NORM_ATTRIB EncounterCatch( Int:id, Int:iPokeID, Int:iItemID, Int:iHP, Int:iMaxHP, Int:status_bonus = 1 )
{
	if ( iPokeID <= 0 || iHP <= 0 || !PlayerHasItem( id, iItemID ) )
		return 0;

	new Int:iRate = str_to_num( PokemonInfo( iPokeID, "CatchRate" ) );
	if ( iRate <= 0 )
		return 0;

	new Float:fCatchChance = str_to_float( ItemInfo( iItemID, "CatchChance" ) );
	if ( fCatchChance <= 0.0 )
		return 0;

	new Int:a = floatround( ( ( ( 3 * iMaxHP ) - ( 2 * iHP ) ) * iRate * fCatchChance * status_bonus ) / ( 3 * iMaxHP ) );
	if ( a >= 255 )
		return -4
	else
	{
		new Int:iWiggles;
		new Int:b = 1048560 / ( sqroot( sqroot( 16711680 / a ) ) );
		for ( new Int:i = 0; i < 4; i++ )
		{
			if ( random_num( 0, 65535 ) <= b )
				iWiggles++;
		}
		if ( iWiggles == 4 )
			return -4;
		return iWiggles;
	}

	return 0;
}

PM_FUNC_NORM_ATTRIB EncounterFight( Int:iPlayer )
{
	if ( PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON ) > 0 )
		return 0;

	new Int:iPokeNum = PlayerGetInfo( iPlayer, PINFO_ACTIVE_POKENUM );
	if ( g_iPlayerPokemonStats[ iPlayer ][ iPokeNum ][ POKESTAT_HP ] <= 0 )
		return 0;

	new Int:iEncounterSize = ArraySize( g_iScriptEncounters ) / 2;

	if ( iEncounterSize )
	{
		new Int:iEncounterNum = random( iEncounterSize );

		new Int:iPokeID = ArrayGetCell( g_iScriptEncounters, ( iEncounterNum * 2 ) );
		new Int:iLevel = ArrayGetCell( g_iScriptEncounters, ( iEncounterNum * 2 ) + 1 );

		EncounterForce( iPlayer, iPokeID, iLevel );

		ArrayClear( g_iScriptEncounters );
		return 1;
	}

	return 0;
}

PM_FUNC_NORM_ATTRIB EncounterForce( Int:iPlayer, Int:iPokeID, Int:iLevel, Int:iIVs = -1 )
{
	new Int:iEncounterID = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON );
	if ( iEncounterID > 0 )
	{
		DHudEventMessage( iPlayer, "%s ran away!", PokeToName( iEncounterID ) );
	}

	PlayerSetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON, iPokeID );
	PlayerSetInfo( iPlayer, PINFO_ENCOUNTER_LEVEL, iLevel );

	if ( iIVs == -1 )
		iIVs = StatNewIVs();
	PlayerSetInfo( iPlayer, PINFO_ENCOUNTER_HP, PokemonMaxHP( iPokeID, iLevel, iIVs ) );
	PlayerSetInfo( iPlayer, PINFO_ENCOUNTER_IVS, iIVs );
	PlayerSetInfo( iPlayer, PINFO_ENCOUNTER_WIGGLES, 0 );

	new Int:iEncounterProps;

	if ( PokemonType( iPokeID ) & TYPE_GHOST && PlayerHasItem( iPlayer, NameToItem( "Silph Scope" ) ) == -1 )
	{
		iEncounterProps |= ENCPROP_GHOST;
		DHudEventMessage( iPlayer, "A Ghost appeared!" );
	}
	else
	{
		DHudEventMessage( iPlayer, "A wild %s appeared!", PokeToName( iPokeID ) );
	}

	PlayerSetInfo( iPlayer, PINFO_ENCOUNTER_PROPS, iEncounterProps );
}

PM_FUNC_NORM_ATTRIB EncounterRun( Int:iPlayer )
{
	pokemod_funcstart_debug( "EncounterRun" );

	if ( PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON ) > 0 )
	{
		PlayerSetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON, 0 );
		DHudEventMessage( iPlayer, "You ran away!" );

		pokemod_funcend_debug( "EncounterRun Successful" );
		return true;
	}

	pokemod_funcend_debug( "EncounterRun" );

	return false;
}

PM_FUNC_NORM_ATTRIB EncounterMenu( Int:iPlayer )
{
	new Int:iEncounterID = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_POKEMON );
	if ( iEncounterID <= 0 )
	{
		return;
	}

	pokemod_funcstart_debug( "EncounterMenu" );

	new String:szEncounterName[ NAME_LEN ];
	new Int:iEncounterProps = PlayerGetInfo( iPlayer, PINFO_ENCOUNTER_PROPS );

	if ( iEncounterProps & ENCPROP_GHOST )
	{
		copy( szEncounterName, charsmax(szEncounterName), "\dGhost" );
	}
	else
	{
		formatex( szEncounterName, charsmax(szEncounterName), "wild %s", PokeToName( iEncounterID ) );
	}

	new Int:iMenu = MenuCreate( "Fighting a %s", szEncounterName );

	MenuAddItem( iMenu, "pokedex", "Pokedex" );
	MenuAddItem( iMenu, "poke", "Change Pokemon" );
	MenuAddItem( iMenu, "item", "Use Item" );
	MenuAddItem( iMenu, "run", "Run" );

	new Array:iPlayerItems = g_iPlayerItems[ iPlayer ];
	new Int:iItemSize = ArraySize( iPlayerItems ) / _:PLAYER_ITEM;

	new String:szData[ 64 ];

	for ( new Int:iItemID, iItemNum; iItemNum < iItemSize; iItemNum++ )
	{
		iItemID = ArrayGetCell( iPlayerItems, ( ( iItemNum * _:PLAYER_ITEM ) + _:ITEM_ID ) );
		if ( _:ArrayGetCell( g_iItemProps, iItemID ) & ( 1 << _:ITEM_AUTO_CATCH ) )
		{
			formatex( szData, charsmax(szData), "catch%d", iItemID );
			MenuAddItem( iMenu, szData, "Throw %s", ItemToName( iItemID ) );
		}
	}

	MenuExit( iPlayer, iMenu, .bExitOption = true );

	MenuDisplay( iPlayer, iMenu, MENU_ENCOUNTER );

	pokemod_funcend_debug( "EncounterMenu" );
}


